Add: automatic AICPU architecture defaults (a2a3/a5) - #1521
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAICPU thread configuration now uses ChangesAICPU auto-resolution
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant TestCase
participant DeviceRunner
participant TopologyProbe
participant Runtime
TestCase->>DeviceRunner: submit config with aicpu_thread_num=0
DeviceRunner->>TopologyProbe: probe usable AICPU cores
TopologyProbe-->>DeviceRunner: return usable count
DeviceRunner->>Runtime: write resolved thread count
Runtime-->>TestCase: launch with resolved configuration
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
3a46dec to
0f7adad
Compare
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/a2a3/platform/onboard/host/device_runner.cpp`:
- Around line 330-337: Keep the resolved AICPU count consistent across runtime
and launch/setup state: in src/a2a3/platform/onboard/host/device_runner.cpp
lines 330-337, propagate resolved_aicpu to launch_aicpu_num or use the updated
Runtime getter for subsequent calls; in
src/a2a3/platform/sim/host/device_runner.cpp lines 234-239 and
src/a5/platform/sim/host/device_runner.cpp lines 217-222, write each resolved
fallback value back via runtime.set_aicpu_thread_num(...).
In `@src/a2a3/platform/sim/host/device_runner.cpp`:
- Around line 234-239: After resolving the zero-value fallback in the launch
flow, write the resulting launch_aicpu_num back to the Runtime object before it
is passed to AICPU execution and setup. Update the existing runtime thread-count
state used by get_aicpu_thread_num(), while preserving configured nonzero values
and the PLATFORM_DEFAULT_AICPU_THREAD_NUM fallback.
In `@src/a5/platform/onboard/host/device_runner.cpp`:
- Around line 159-163: Update the launch_aicpu_num normalization in the device
runner to treat only aicpu_thread_num equal to zero as auto; preserve negative
values so validate_launch_aicpu_num() rejects them instead of converting them to
PLATFORM_DEFAULT_AICPU_THREAD_NUM.
- Around line 159-163: After the AICPU resolution logic that computes
resolved_aicpu, update Runtime unconditionally via
runtime.set_aicpu_thread_num(resolved_aicpu). Place this after the allowed-CPU
clamping path so both configured and auto modes publish the effective active
count, including when no adjustment branch is taken.
In `@src/a5/platform/sim/host/device_runner.cpp`:
- Around line 217-222: After resolving the platform default in the launch setup,
write the resulting launch_aicpu_num back through the Runtime setter so
runtime.get_aicpu_thread_num() matches the count used by init_l2_swimlane and
AICPU execution. Keep the existing explicit-count behavior unchanged.
In `@src/common/platform/onboard/host/device_runner_base.cpp`:
- Around line 1168-1174: Update the clamp warning in the thread-count
calculation to log desired instead of requested, so auto mode reports the
architecture default selected by the desired calculation. Preserve the existing
warning text, usable count, and scheduler count.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 8a54c647-7f3b-42da-ab4b-d4cd2bea8eac
📒 Files selected for processing (92)
examples/a2a3/tensormap_and_ringbuffer/benchmark_bgemm/test_benchmark_bgemm.pyexamples/a2a3/tensormap_and_ringbuffer/merge_pipeline_barrier/test_merge_pipeline_barrier.pyexamples/a2a3/tensormap_and_ringbuffer/paged_attention/test_paged_attention.pyexamples/a2a3/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention.pyexamples/a2a3/tensormap_and_ringbuffer/paged_attention_ringbuffer/test_paged_attention_ringbuffer.pyexamples/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll.pyexamples/a2a3/tensormap_and_ringbuffer/qwen3_14b_decode/test_qwen3_14b_decode.pyexamples/a2a3/tensormap_and_ringbuffer/scalar_data_test/test_scalar_data.pyexamples/a2a3/tensormap_and_ringbuffer/vector_example/test_vector_example.pyexamples/a5/tensormap_and_ringbuffer/bgemm/test_bgemm.pyexamples/a5/tensormap_and_ringbuffer/paged_attention/test_paged_attention.pyexamples/a5/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention.pyexamples/a5/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll.pyexamples/a5/tensormap_and_ringbuffer/vector_example/test_vector_example.pypython/simpler/task_interface.pysimpler_setup/scene_test.pysrc/a2a3/docs/hardware.mdsrc/a2a3/platform/include/common/platform_config.hsrc/a2a3/platform/onboard/host/device_runner.cppsrc/a2a3/platform/sim/host/device_runner.cppsrc/a5/docs/hardware.mdsrc/a5/platform/include/common/platform_config.hsrc/a5/platform/onboard/host/device_runner.cppsrc/a5/platform/sim/host/device_runner.cppsrc/common/platform/onboard/host/device_runner_base.cppsrc/common/platform/onboard/host/device_runner_base.hsrc/common/platform/sim/host/device_runner_base.cppsrc/common/task_interface/call_config.htests/st/a2a3/host_build_graph/available_aicore_counts/test_available_aicore_counts.pytests/st/a2a3/host_build_graph/bgemm/test_bgemm.pytests/st/a2a3/host_build_graph/dfx/dep_gen/test_dep_gen.pytests/st/a2a3/host_build_graph/dump_args/test_dump_args_example.pytests/st/a2a3/host_build_graph/matmul/test_matmul.pytests/st/a2a3/host_build_graph/paged_attention/test_paged_attention.pytests/st/a2a3/host_build_graph/prepared_callable/test_prepared_callable.pytests/st/a2a3/host_build_graph/run_stream_reuse/test_run_stream_reuse.pytests/st/a2a3/host_build_graph/vector_example/test_vector_example.pytests/st/a2a3/tensormap_and_ringbuffer/alternating_matmul_add/test_alternating_matmul_add.pytests/st/a2a3/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.pytests/st/a2a3/tensormap_and_ringbuffer/batch_paged_attention/test_batch_paged_attention.pytests/st/a2a3/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.pytests/st/a2a3/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.pytests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.pytests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.pytests/st/a2a3/tensormap_and_ringbuffer/dfx/pmu/test_pmu.pytests/st/a2a3/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.pytests/st/a2a3/tensormap_and_ringbuffer/dynamic_register/test_dynamic_register.pytests/st/a2a3/tensormap_and_ringbuffer/fanin_lookup_perf/test_fanin_lookup_perf.pytests/st/a2a3/tensormap_and_ringbuffer/mixed_example/test_mixed_example.pytests/st/a2a3/tensormap_and_ringbuffer/multi_round_paged_attention/test_multi_round_paged_attention.pytests/st/a2a3/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.pytests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.pytests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_4dims/test_paged_attention_unroll_4dims.pytests/st/a2a3/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_batch_dispatch_oob/test_spmd_batch_dispatch_oob.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention/test_spmd_paged_attention.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention_highperf/test_spmd_paged_attention_highperf.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.pytests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.pytests/st/a2a3/tensormap_and_ringbuffer/test_l3_dependency.pytests/st/a2a3/tensormap_and_ringbuffer/test_l3_group.pytests/st/a5/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.pytests/st/a5/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.pytests/st/a5/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.pytests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.pytests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.pytests/st/a5/tensormap_and_ringbuffer/dfx/pmu/test_pmu.pytests/st/a5/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.pytests/st/a5/tensormap_and_ringbuffer/mixed_example/test_mixed_example.pytests/st/a5/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.pytests/st/a5/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.pytests/st/a5/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.pytests/st/a5/tensormap_and_ringbuffer/simt_basic/test_simt_basic.pytests/st/a5/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.pytests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.pytests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.pytests/st/a5/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.pytests/st/a5/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.pytests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.pytests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.pytests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.pytests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_mix_spill/test_spmd_sync_start_mix_spill.pytests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.pytests/st/task_timing/task_timing_slots/test_task_timing_e2e.pytests/ut/py/test_chip_worker.py
💤 Files with no reviewable changes (72)
- tests/st/a5/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py
- examples/a2a3/tensormap_and_ringbuffer/benchmark_bgemm/test_benchmark_bgemm.py
- tests/st/a2a3/tensormap_and_ringbuffer/alternating_matmul_add/test_alternating_matmul_add.py
- examples/a2a3/tensormap_and_ringbuffer/merge_pipeline_barrier/test_merge_pipeline_barrier.py
- examples/a5/tensormap_and_ringbuffer/vector_example/test_vector_example.py
- tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py
- tests/st/a5/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py
- examples/a2a3/tensormap_and_ringbuffer/scalar_data_test/test_scalar_data.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py
- tests/st/a5/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py
- tests/st/a5/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py
- tests/st/a2a3/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py
- tests/st/a5/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py
- tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py
- examples/a2a3/tensormap_and_ringbuffer/paged_attention_ringbuffer/test_paged_attention_ringbuffer.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py
- tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py
- tests/st/a2a3/host_build_graph/bgemm/test_bgemm.py
- tests/st/a5/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py
- tests/st/a5/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py
- tests/st/a2a3/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py
- tests/st/a2a3/host_build_graph/vector_example/test_vector_example.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py
- examples/a2a3/tensormap_and_ringbuffer/qwen3_14b_decode/test_qwen3_14b_decode.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_mix_spill/test_spmd_sync_start_mix_spill.py
- tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py
- tests/st/a5/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py
- tests/st/a2a3/host_build_graph/matmul/test_matmul.py
- examples/a2a3/tensormap_and_ringbuffer/vector_example/test_vector_example.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py
- tests/st/a2a3/host_build_graph/available_aicore_counts/test_available_aicore_counts.py
- tests/st/a2a3/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_batch_dispatch_oob/test_spmd_batch_dispatch_oob.py
- examples/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll.py
- tests/st/a2a3/tensormap_and_ringbuffer/multi_round_paged_attention/test_multi_round_paged_attention.py
- tests/st/a2a3/host_build_graph/prepared_callable/test_prepared_callable.py
- tests/st/a2a3/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py
- examples/a5/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py
- tests/st/a2a3/host_build_graph/dump_args/test_dump_args_example.py
- tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py
- examples/a2a3/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py
- tests/st/a2a3/host_build_graph/paged_attention/test_paged_attention.py
- tests/st/a2a3/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py
- tests/st/a2a3/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py
- examples/a5/tensormap_and_ringbuffer/bgemm/test_bgemm.py
- tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_4dims/test_paged_attention_unroll_4dims.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py
- tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py
- tests/st/a5/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention_highperf/test_spmd_paged_attention_highperf.py
- tests/st/a5/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py
- examples/a5/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll.py
- tests/st/task_timing/task_timing_slots/test_task_timing_e2e.py
- tests/st/a2a3/host_build_graph/dfx/dep_gen/test_dep_gen.py
- examples/a5/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py
- tests/st/a2a3/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py
- tests/st/a2a3/tensormap_and_ringbuffer/fanin_lookup_perf/test_fanin_lookup_perf.py
- tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention/test_spmd_paged_attention.py
- tests/st/a2a3/tensormap_and_ringbuffer/dynamic_register/test_dynamic_register.py
- tests/st/a2a3/tensormap_and_ringbuffer/batch_paged_attention/test_batch_paged_attention.py
- tests/st/a2a3/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py
83d054d to
59d5824
Compare
sunkaixuan2018
left a comment
There was a problem hiding this comment.
The auto/partial-good direction is useful, but I think a few issues need to be addressed or clarified:
-
The a5 usable count is not the device-visible AICPU pool.
The host probe reads host-sideOCCUPY=0x1feand obtains 8 CPUs, while the documented device-side pool is0x1f8with only 6 schedulable CPUs. Although the default active count is 5,aicpu_launch_countis still set to 8. The existing hardware documentation states that launching more than the device-side OCCUPY popcount can stall the production affinity gate and lead to a timeout. Both the active count and launch count should be derived from the actual device-visible pool. -
The thread-count and CPU-selection policy should consider cluster affinity.
resolve_aicpu_thread_num()currently only uses the total number of usable CPUs. Under PG, the remaining CPUs may be distributed across multiple clusters. For example, if four CPUs remain in a 2+2 distribution, the resolver still selects four threads and the affinity selector falls back to a cross-cluster layout. This may reintroduce the NUMA-crossing performance regression addressed by #1045/#1119.I suggest evaluating this on the current CPU architecture by marking different CPU cores as unavailable to emulate representative PG layouts, such as CPUs concentrated in one cluster or distributed across multiple clusters. Performance tests can then be used to compare different thread counts and placements and determine the best policy for each scenario—for example, whether keeping Scheduler threads, and preferably the orchestrator, in the same cluster is better than using more threads across clusters. The deterministic selector and tests from #1119 can be used as a reference. If a complete topology-aware policy is too complex for this PR, it would be reasonable to document the limitation and optimize it in a follow-up PR.
-
The new a5 failure path leaks the AICore register buffer.
init_aicore_register_addresses()allocateskernel_args_.args.regsbefore topology resolution, butregs_cleanupis created only afterwards. Returns caused by probe failure,usable < 2, or affinity-selection failure therefore skip cleanup. The guard should be installed before the allocation, as in the a2a3 implementation, or topology resolution should happen before allocating the buffer. -
aicpu_thread_num=1is accepted but is not a valid normal-run configuration.
On a5 onboard it skips topology setup, after which the device kernel rejects the missing affinity inputs. In the tensormap runtime it also means one orchestrator and zero schedulers. The public configuration should probably accept only0(auto) or[2, MAX]; any internal one-thread initialization path should be kept separate. -
The core PG behavior needs deterministic tests.
The current test changes mainly remove explicit thread counts and exercise the healthy auto path indirectly. Please add host-side tests forusable < default,usable < 2, explicit values larger than usable,aicpu_thread_num=1, and PG layouts distributed across multiple clusters. The tests should also verify that the resolved active count, selected CPUs, Runtime metadata, DFX counts, and actual launch count remain consistent.
There are also several user-facing documents that still list the default as 3, and the generic “1 orchestrator + N schedulers” wording does not match host_build_graph, where the device-side thread roles differ.
59d5824 to
dfe7e8d
Compare
|
Implemented the initial topology-local auto policy and addressed the actionable review findings:
Local validation:
The full sim run was also attempted, but concurrent a2a3sim/a5sim execution caused shared |
dfe7e8d to
da3132e
Compare
da3132e to
55a4951
Compare
192e61c to
69480d6
Compare
Review 总结(/review-pr)核心逻辑正确、CI 全绿(含 🔴 Must fix —— 文档仍把默认值写成
|
| 文件 | 内容 |
|---|---|
docs/capability-survey.md:66 |
"aicpu_thread_num is 3 (call_config.h:112)" —— 还精确引了行号 |
docs/task-flow.md:213 |
int32_t aicpu_thread_num = 3; |
docs/user/reference/python-api.md:123 |
面向用户的 API 表默认列写 3 |
docs/chip-level-arch.md:151 |
config.aicpu_thread_num = 3 |
docs/getting-started.md:217 |
"aicpu_thread_num": 3, |
docs/task-flow.md:686 |
CallConfig(aicpu_thread_num=3) |
🟠 Should fix —— 示例 README 仍描述已被本 PR 删除的 per-case 配置
对应目录的 test CASES 里 "config": {"aicpu_thread_num": 4} 已删,README 描述未同步:
examples/a2a3/tensormap_and_ringbuffer/scalar_data/README.md:52examples/a2a3/tensormap_and_ringbuffer/paged_attention/README.md:24examples/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/README.md:48
说明:a2a3 auto→4,实际线程数不变,数字 "4" 不算错;错在把它描述成"该 case 显式设置的配置项",而该配置项已被删除。
🟡 a5 hardware.md 范围表述
src/a5/docs/hardware.md:142 标注显式范围 [2, 7],但 onboard 实际上限为设备可见池的 6(显式传 7 能过 validate 却会在 compute_allowed_cpus 阶段运行时报错)。虽有"onboard requires the device-visible pool to fit"兜底,但 [2,7] 仍可能误导,建议点明"编译期上限 7 / onboard 有效上限 6"。
可留(非漂移)
dfx 三处 min(aicpu_thread_num, kMaxCollectorThreads)、各 RUNTIME_LOGIC.md 的 "With aicpu_thread_num=4"、remote-l3 protocol.md wire 字段、l3 workers README 的 "=2 required" —— 描述运行时行为或仍有效的显式用法,不受默认值变更影响。docs/testing.md:606、docs/user/how-to/write-and-run-a-kernel.md:58 里的 "config": {"aicpu_thread_num": 4} 是演示"可以这样设"的机制示例,合法,可留(改成 auto 更贴合新默认)。
背景记录(已与 reviewer 讨论,本 PR 不处理)
- a2a3 用
resolve_aicpu_thread_num做部分良品钳制、a5 用严格匹配,二者不对称:源于两 arch 选核策略不同(a5compute_allowed_cpus按 SMT/物理拓扑分组,a2a3 按 cluster 扁平分组)。后续会统一更新选核策略,此处有意保留不对称。建议在 a5run()加一行注释说明"为何不复用 common base 里的resolve_aicpu_thread_num",否则该 helper 放在公共基类却只被 a2a3 调用,读者易误判为遗漏。 resolve_aicpu_thread_num的降级分支(usable < 2报错 /total < desired告警)暂不补测试:随后续选核策略更新一并处理。aicpu_thread_num未像block_dim(Refactor: remove the user-facing block_dim knob #1309)那样彻底删旋钮:合理——block_dim只有唯一正确值(整设备),而aicpu_thread_num有真实非默认需求(如examples/workers/l3/*的 serving loop 要求= 2)。建议在CallConfig注释里点明"因 L3 等场景需要而保留显式覆盖",以免读者误以为是过渡态。
Verdict
Approve(建议补文档) —— 逻辑与硬件验证均通过,阻塞项仅为上述文档一致性,建议随本 PR 一并修 🔴/🟠 两档。
Use zero as the default AICPU thread sentinel while preserving explicit per-run overrides. - Resolve auto to four active threads on a2a3 and five on a5. - Keep affinity, launch, Runtime, and DFX state consistent with the effective thread count. - Resolve simulation defaults directly without hardware topology probing. - Reject one-thread normal runs and align the a5 host-visible launch pool with device availability. - Align public references and example descriptions with auto selection and document the a5 onboard pool limit.
69480d6 to
6b63b3f
Compare
|
@ChaoZheng109 Addressed the documentation consistency findings:
The documentation-only changes pass the full local pre-commit suite, including markdownlint. |
hw-native-sys#1587 moved three contracts without moving the text that described them, and left one failure mode expressed as a noexcept violation. Geometry. resolve_block_dim() and prepare_launch_shape() no longer write block_dim_ or worker_count_; activate_launch_shape() latches both on the executor thread immediately before run(). The comment and the LOG_ERROR in each onboard run() still named prepare_launch_shape, so the one diagnostic a future reader greps pointed at a function that latches nothing. hw-native-sys#1521 later edited the line directly below that comment and left it standing, which is how a stale comment survives. The simulation runners keep their wording: SimDeviceRunnerBase::prepare_launch_shape does still assign block_dim_. Streams. RunStreamSlots became a two-thread class when native prepare started provisioning the successor's slot while the executor retires the predecessor's. Per-slot handles are safe — admission gives each slot one owner — but created_count_ is shared across owners and is also read from an unrelated thread through get_run_stream_set_create_count, so it is now atomic and the ownership rule is stated on the class. Thread selection. restore_native_run_thread_selection was noexcept while run_selection() could throw: on a thread created by create_thread the per-thread block does not exist yet, so installation allocates. Split out a non-throwing try_run_selection() and let restore abort with a message on the unrecoverable path. Returning instead would leave the thread on the default slot and bank, addressing storage another lease owns, and a freshly started thread has no channel to report the failure through. B6c removes the mechanism outright; until then the failure is diagnosable rather than a bare terminate. Symbol loading. Since every required pipeline symbol became a strict load, the dominant cause of a dlsym failure is a host runtime out of sync with the tree that consumes it. Say so in the error, which otherwise reports only the missing name. Also spell the successor-already-staged test as occupied > 1, since the loop above it has already rejected every predecessor that may not carry one, and record that simulation discards native-run identity by design.
) #1587 moved three contracts without moving the text that described them, and left one failure mode expressed as a noexcept violation. Geometry. resolve_block_dim() and prepare_launch_shape() no longer write block_dim_ or worker_count_; activate_launch_shape() latches both on the executor thread immediately before run(). The comment and the LOG_ERROR in each onboard run() still named prepare_launch_shape, so the one diagnostic a future reader greps pointed at a function that latches nothing. #1521 later edited the line directly below that comment and left it standing, which is how a stale comment survives. The simulation runners keep their wording: SimDeviceRunnerBase::prepare_launch_shape does still assign block_dim_. Streams. RunStreamSlots became a two-thread class when native prepare started provisioning the successor's slot while the executor retires the predecessor's. Per-slot handles are safe — admission gives each slot one owner — but created_count_ is shared across owners and is also read from an unrelated thread through get_run_stream_set_create_count, so it is now atomic and the ownership rule is stated on the class. Thread selection. restore_native_run_thread_selection was noexcept while run_selection() could throw: on a thread created by create_thread the per-thread block does not exist yet, so installation allocates. Split out a non-throwing try_run_selection() and let restore abort with a message on the unrecoverable path. Returning instead would leave the thread on the default slot and bank, addressing storage another lease owns, and a freshly started thread has no channel to report the failure through. B6c removes the mechanism outright; until then the failure is diagnosable rather than a bare terminate. Symbol loading. Since every required pipeline symbol became a strict load, the dominant cause of a dlsym failure is a host runtime out of sync with the tree that consumes it. Say so in the error, which otherwise reports only the missing name. Also spell the successor-already-staged test as occupied > 1, since the loop above it has already rejected every predecessor that may not carry one, and record that simulation discards native-run identity by design.
Summary
aicpu_thread_numno longer needs to be specified by default. A value of0is the automatic sentinel, while explicit per-run values remain supported.
with the selected architecture default or explicit override, and require at
least one orchestration thread plus one scheduler thread.
the architecture default.
the AICPU OS so its launch pool matches device-visible availability.
aicpu_thread_numentries;callers can still provide an explicit value in
[2, PLATFORM_MAX].Validation
python -m pytest tests/ut/py/test_chip_worker.py -q— 26 passedpre-commit run --hook-stage commit— passed